
%include "src/descriptor.inc"
;org 0100h
org 07c00h
  jmp start

[SECTION .gdt]
;GDT
LABEL_GDT:         descriptor 0, 0, 0   ; null descriptor
LABEL_DESC_CODE32: descriptor 0, SegCode32Len-1, DA_C+DA_32  ; code segment 32 bit
LABEL_DESC_VIDEO:  descriptor 0B8000h, 0ffffh, DA_DRW         ; video base address
;GDT end
GdtLen equ $-LABEL_GDT    ; length
GdtPtr dw GdtLen          ; GDT limit 
       dd 0               ; base address

;GDT Selector
SelectorCode32  equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo   equ LABEL_DESC_VIDEO  - LABEL_GDT
len_gdt equ $-LABEL_GDT
; END of [SECTION .gdt]       

[SECTION .s16]
[BITS 16]
start:
  mov ax, cs
  mov ds, ax
  mov es, ax
  mov ss, ax
  mov sp, 0100h

  ;call init_display
 
  ; init 32 bit code segment descriptor
  xor eax, eax
  mov ax, cs
  shl eax, 4
  add eax, LABEL_SEG_CODE32
  mov word [LABEL_DESC_CODE32+2], ax
  shr eax, 16
  mov byte [LABEL_DESC_CODE32+4], al
  mov byte [LABEL_DESC_CODE32+7], ah

  ; ready for load gdtr
  xor eax, eax
  mov ax, ds
  shl eax, 4
  add eax, LABEL_GDT    ; eax <- gdt base address
  mov dword [GdtPtr+2], eax   ; [GdtPtr+2] <- gdt base address

  ; load gdtr
  lgdt [GdtPtr]

  ; close interrupt
  cli

  ; open address line A20
  in al, 92h
  or al, 00000010b
  out 92h, al

  ; change to protected mode
  mov eax, cr0
  or eax, 1
  mov cr0, eax

  ; in protected mode
  jmp dword SelectorCode32:0

;init_display: 
;	mov ax,0x4f02 
;	mov bx,0x115 
;	int 10h 
;	ret 

len_segcode16 equ $-start
[SECTION .text]
boot_message: db "Hello, Simple OS!"
len_boot_message equ $-boot_message

[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
  mov ax, SelectorVideo
  mov gs, ax

  ; show message
  mov cx, len_boot_message
  mov edi, (80*10+12)*2
  mov bx, boot_message
  mov ah, 0ch

s:mov al, [ds:bx]
  mov [gs:edi], ax
  inc bx
  add edi, 2
  loop s
  ; show message end

  mov ah, 08h
  mov dl, 00h
  int 13h
  jc read_failed
  
  ; ok
  xor ax, ax
  mov ah, 0ch
  mov al, 3 
  add al, 48
  mov [gs:edi], ax

read_failed:
  jmp $
SegCode32Len equ $-LABEL_SEG_CODE32
;END of [SECTION .s32]


times 510-($-$$+8+len_gdt+len_boot_message+len_segcode16)  db 0   ; fill the rest space with 512 bytes
dw    0xaa55             ; end flag
